package com.edu.security;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/*
1.@EnableGlobalMethodSecurity注解
   是 spring security 用米开启方法级别权限验证注解的注解
2.prePostEnabled=true 用来开启@PreAuthorize 和 @PostAuthorize 注解验证功能.
  (这两项注解设置在控制器之上)允许在方法上使用表达式定义安全规则
 */
@Configuration
@EnableWebSecurity  //启用MVC控制层的安全注解
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private MyAuthenticationSuccessHandler successHandler;
    @Autowired
    private MyAccessDeniedHandler deniedHandler;

    //1.方法一
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder builder) throws Exception {
        builder.userDetailsService(userDetailsService).passwordEncoder( new BCryptPasswordEncoder());
    }
    //2.方法二
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers(
                        "/login",
                        "/form",
                        "/static/**",
                        "/System/User/**",
                        "/Paper/**",
                        "/Front/**",
                        "/Student/**",
                        "/Exam/**",
                        "/StuUser/**",
                        "/Teacher/**"
                )
                .permitAll()
                .anyRequest()
                .authenticated();

        //2.这里来设置登录相关的处理办法
        http.formLogin()
                .loginPage("/login")                             //页面映射地址
                .loginProcessingUrl("/doLogin")                  //登录的处理页
                .successHandler(successHandler)                  //成功交给这个处理器
                .failureUrl("/loginFailed")  //失败跳转到这个页
                .permitAll();                                   //全部允许放行

        //3.设置禁用跨站伪造攻击的防护功能
        http.csrf().disable();

        //4.配置登出处理的办法
        http.logout()
                .logoutSuccessUrl("/login")                     //登出系统跳转到哪里
                .invalidateHttpSession(true);                   //要不要销毁会话

        //5.设置无权限访问的处理器
        http.exceptionHandling()
                .accessDeniedHandler(deniedHandler);

    }
}
